package com.ygxsk.carhome.alertview;

import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Looper;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.blankj.utilcode.util.ColorUtils;
import com.ygxsk.carhome.R;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Sai on 15/8/9.
 * 精仿iOSAlertViewController控件
 * 点击取消按钮返回 －1，其他按钮从0开始算
 */
public class AlertView {
    public enum Style {
        ActionSheet,
        Alert
    }

    private final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM
    );
    /**
     * 水平方向上最多两个按钮的
     */
    public static final int HORIZONTAL_BUTTONS_MAXCOUNT = 2;
    public static final int CANCELPOSITION = -1;//点击取消按钮返回 －1，其他按钮从0开始算

    private String title;
    private String msg;
    private String[] destructive;
    private String[] others;
    private List<String> mDestructive;
    private List<String> mOthers;
    private String cancel;
    private final ArrayList<String> mDatas = new ArrayList<String>();

    private final WeakReference<Context> contextWeak;
    private ViewGroup contentContainer;
    private ViewGroup decorView;//activity的根View
    private ViewGroup rootView;//AlertView 的 根View
    private ViewGroup loAlertHeader;//窗口headerView

    private Style style = Style.Alert;

    private OnDismissListener onDismissListener;
    private final OnItemClickListener onItemClickListener;
    private boolean isShowing;

    private Animation outAnim;
    private Animation inAnim;
    private int gravity = Gravity.CENTER;

    public AlertView(Builder builder) {
        this.contextWeak = new WeakReference<>(builder.context);
        this.style = builder.style;
        this.title = builder.title;
        this.msg = builder.msg;
        this.cancel = builder.cancel;
        this.destructive = builder.destructive;
        this.others = builder.others;
        this.onItemClickListener = builder.onItemClickListener;

        initData(title, msg, cancel, destructive, others);
        initViews();
        init();
        initEvents();
    }

    public AlertView(String title,//
                     String msg,//
                     String cancel, //
                     String[] destructive, //
                     String[] others, //
                     Context context, //
                     Style style,//
                     OnItemClickListener onItemClickListener) {

        this.contextWeak = new WeakReference<>(context);

        if (style != null)
            this.style = style;
        this.onItemClickListener = onItemClickListener;

        initData(title, msg, cancel, destructive, others);

        initViews();

        init();

        initEvents();
    }

    /**
     * 获取数据
     */
    protected void initData(String title, String msg, String cancel, String[] destructive, String[] others) {

        this.title = title;

        this.msg = msg;


        if (destructive != null) {
            this.mDestructive = Arrays.asList(destructive);
            this.mDatas.addAll(mDestructive);
        }

        if (others != null) {
            this.mOthers = Arrays.asList(others);
            this.mDatas.addAll(mOthers);
        }

        if (cancel != null) {//这个cancel不是空值那么 第0个位置就是cancel
            this.cancel = cancel;
            if (style == Style.Alert && mDatas.size() < HORIZONTAL_BUTTONS_MAXCOUNT) {
                this.mDatas.add(0, cancel);
            }
        }

    }

    protected void initViews() {

        Context context = contextWeak.get();

        //LogUtils.d("itchen--context=="+context.getClass().getName());

        if (context == null) {
            return;
        }

        LayoutInflater layoutInflater = LayoutInflater.from(context);

        decorView = (ViewGroup) ((Activity) context).getWindow().getDecorView().findViewById(android.R.id.content);
        rootView = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview, decorView, false);

        rootView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));


        contentContainer = (ViewGroup) rootView.findViewById(R.id.content_container);

        int margin_alert_left_right = 0;

        switch (style) {
            case ActionSheet://列表多个数据
                params.gravity = Gravity.BOTTOM;

                margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_actionsheet_left_right);

                params.setMargins(margin_alert_left_right, 0, margin_alert_left_right, margin_alert_left_right);

                contentContainer.setLayoutParams(params);
                gravity = Gravity.BOTTOM;

                initActionSheetViews(layoutInflater);

                break;


            case Alert://弹窗数据

                params.gravity = Gravity.CENTER;
                margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_alert_left_right);

                params.setMargins(margin_alert_left_right, 0, margin_alert_left_right, 0);

                contentContainer.setLayoutParams(params);

                gravity = Gravity.CENTER;

                initAlertViews(layoutInflater);

                break;
        }
    }

    protected void initHeaderView(ViewGroup viewGroup) {

        loAlertHeader = (ViewGroup) viewGroup.findViewById(R.id.loAlertHeader);

        //标题和消息
        TextView tvAlertTitle = (TextView) viewGroup.findViewById(R.id.tvAlertTitle);

        TextView tvAlertMsg = (TextView) viewGroup.findViewById(R.id.tvAlertMsg);

        //------------------------------------------------------------------------------
        ViewTreeObserver vto = tvAlertMsg.getViewTreeObserver();

        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            @Override
            public boolean onPreDraw() {

                //2019年12月27日 自己手动设置1行居中2行居左的设置
                int lineCount = tvAlertMsg.getLineCount();
                //LogUtils.d("itchen--->获取到的message的行数为："+lineCount);
                //打印结果是：2
                if (lineCount <= 1) {
                    //1行居中
                    tvAlertMsg.setGravity(Gravity.CENTER);
                } else {
                    //2行居左
                    tvAlertMsg.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
                }

                return true;
            }
        });


        //----------------------------------------------------------------------

        if (title != null) {

            if (!TextUtils.isEmpty(title)) {
                tvAlertTitle.setText(title);
            } else {
                tvAlertTitle.setVisibility(View.GONE);
            }

        } else {
            tvAlertTitle.setVisibility(View.GONE);//标题传递空值 自己就设定为gone
        }
        if (msg != null) {

            tvAlertMsg.setText(msg);


        } else {
            tvAlertMsg.setVisibility(View.GONE);
        }
    }

    protected void initListView() {

        Context context = contextWeak.get();

        if (context == null) {
            return;
        }

        ListView alertButtonListView = (ListView) contentContainer.findViewById(R.id.alertButtonListView);

        //把cancel作为footerView

        if (cancel != null && style == Style.Alert) {
            View itemView = LayoutInflater.from(context).inflate(R.layout.item_alertbutton, null);
            TextView tvAlert = (TextView) itemView.findViewById(R.id.tvAlert);
            tvAlert.setText(cancel);
            tvAlert.setClickable(true);
            tvAlert.setTypeface(Typeface.DEFAULT_BOLD);
            //已过时
            //tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_cancel));
            //工具类
            tvAlert.setTextColor(ColorUtils.getColor(R.color.textColor_alert_button_cancel));
            tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_bottom);
            tvAlert.setOnClickListener(new OnTextClickListener(CANCELPOSITION));
            alertButtonListView.addFooterView(itemView);
        }

        //这里应该是第一条时候没有顶部的横线内容
        AlertViewAdapter adapter = new AlertViewAdapter(mDatas, mDestructive, title);

        alertButtonListView.setAdapter(adapter);

        alertButtonListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                if (onItemClickListener != null)
                    onItemClickListener.onItemClick(AlertView.this, position);
                dismiss();
            }
        });
    }

    protected void initActionSheetViews(LayoutInflater layoutInflater) {
        ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview_actionsheet, contentContainer);
        initHeaderView(viewGroup);

        initListView();
        TextView tvAlertCancel = (TextView) contentContainer.findViewById(R.id.tvAlertCancel);
        if (cancel != null) {
            tvAlertCancel.setVisibility(View.VISIBLE);
            tvAlertCancel.setText(cancel);
        }
        tvAlertCancel.setOnClickListener(new OnTextClickListener(CANCELPOSITION));
    }

    /**
     * 普通的弹窗数据内容
     */
    protected void initAlertViews(LayoutInflater layoutInflater) {

        Context context = contextWeak.get();

        if (context == null) {
            return;
        }

        ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview_alert, contentContainer);

        initHeaderView(viewGroup);

        int position = 0;

        //如果总数据小于等于HORIZONTAL_BUTTONS_MAXCOUNT，则是横向button
        //小于或者等于两个，那么就是横向的布局
        if (mDatas.size() <= HORIZONTAL_BUTTONS_MAXCOUNT) {

            ViewStub viewStub = (ViewStub) contentContainer.findViewById(R.id.viewStubHorizontal);

            viewStub.inflate();
            // TODO: 2024/1/18 14:06 使view不被遮挡
//            viewStub.bringToFront();

            LinearLayout loAlertButtons = (LinearLayout) contentContainer.findViewById(R.id.loAlertButtons);

            for (int i = 0; i < mDatas.size(); i++) {

                //LogUtils.d("itchen--外侧->i="+i);

                //如果不是第一个按钮
                if (i != 0) {

                    //LogUtils.d("itchen--内侧->i="+i);
                    //itchen第一个是不需要在左侧添加分割线内容的
                    //添加上按钮之间的分割线
                    View divier = new View(context);

                    //正常的灰色线条
                    //divier.setBackgroundColor(context.getResources().getColor(R.color.bgColor_divier));
                    divier.setBackgroundColor(ColorUtils.getColor(R.color.bgColor_divier));

                    //为了突出显示弄得蓝色线条。为了测试
                    //divier.setBackgroundColor(context.getResources().getColor(R.color.blue));

                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(//
                            (int) context.getResources().getDimension(R.dimen.size_divier), //
                            LinearLayout.LayoutParams.MATCH_PARENT);//

                    loAlertButtons.addView(divier, params);
                }

                View itemView = LayoutInflater.from(context).inflate(R.layout.item_alertbutton, null);
                TextView tvAlert = (TextView) itemView.findViewById(R.id.tvAlert);
                tvAlert.setClickable(true);

                //设置点击效果
                if (mDatas.size() == 1) {

                    tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_bottom);

                } else if (i == 0) {//设置最左边的按钮效果

                    tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_left);

                } else if (i == mDatas.size() - 1) {//设置最右边的按钮效果

                    tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_right);
                }

                String data = mDatas.get(i);
                tvAlert.setText(data);//这是设置的左右的按钮文字

                //【取消】按钮的样式，携带字样和取消 一样。
                if (data == cancel) {

                    //原始代码是自提加粗的，2019年12月10日itchen去掉加粗
                    //tvAlert.setTypeface(Typeface.DEFAULT_BOLD);//字体加粗代码

                    //tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_cancel));
                    tvAlert.setTextColor(ColorUtils.getColor(R.color.textColor_alert_button_cancel));
                    tvAlert.setOnClickListener(new OnTextClickListener(CANCELPOSITION));
                    position = position - 1;

                } else if (mDestructive != null && mDestructive.contains(data)) {//按钮高亮的样式

                    //这里是为了让左右两侧的按钮 点击时候具备同样的字体样式。
                    //tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_cancel));
                    //过时的方法
                    tvAlert.setTextColor(ColorUtils.getColor(R.color.textColor_alert_button_cancel));
                    //原始代码内容
                    //tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_destructive));
                }

                tvAlert.setOnClickListener(new OnTextClickListener(position));
                position++;

                loAlertButtons.addView(itemView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT, 1));
            }

        } else {

            //如果按钮多于2个 那么就默认使用竖直的列表。
            ViewStub viewStub = (ViewStub) contentContainer.findViewById(R.id.viewStubVertical);
            viewStub.inflate();
            initListView();

        }

    }

    protected void init() {
        inAnim = getInAnimation();
        outAnim = getOutAnimation();
    }

    protected void initEvents() {
    }

    public AlertView addExtView(View extView) {
        loAlertHeader.addView(extView);
        return this;
    }

    /**
     * show的时候调用
     *
     * @param view 这个View
     */
    private void onAttached(View view) {
        isShowing = true;
        decorView.addView(view);
        contentContainer.startAnimation(inAnim);
    }

    /**
     * 添加这个View到Activity的根视图
     */
    public void show() {
        if (isShowing()) {
            return;
        }
        onAttached(rootView);
    }

    /**
     * 检测该View是不是已经添加到根视图
     *
     * @return 如果视图已经存在该View返回true
     */
    public boolean isShowing() {

        if (rootView.getParent() != null) {
            return rootView.getParent() != null && isShowing;
        }

        //2019年08月05日原始代码：return rootView.getParent() != null && isShowing;
        return isShowing;
    }

    public void dismiss() {
        //消失动画
        outAnim.setAnimationListener(outAnimListener);
        contentContainer.startAnimation(outAnim);
    }

    public void dismissImmediately() {
        decorView.removeView(rootView);
        isShowing = false;
        if (onDismissListener != null) {
            onDismissListener.onDismiss(this);
        }

    }

    public Animation getInAnimation() {
        Context context = contextWeak.get();
        if (context == null)
            return null;

        int res = AlertAnimateUtil.getAnimationResource(this.gravity, true);
        return AnimationUtils.loadAnimation(context, res);
    }

    public Animation getOutAnimation() {
        Context context = contextWeak.get();
        if (context == null)
            return null;

        int res = AlertAnimateUtil.getAnimationResource(this.gravity, false);
        return AnimationUtils.loadAnimation(context, res);
    }

    public AlertView setOnDismissListener(OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
        return this;
    }

    class OnTextClickListener implements View.OnClickListener {

        private final int position;

        public OnTextClickListener(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View view) {
            if (onItemClickListener != null)
                onItemClickListener.onItemClick(AlertView.this, position);
            dismiss();
        }
    }

    /*private Animation.AnimationListener outAnimListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            dismissImmediately();
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };*/


    private final Animation.AnimationListener outAnimListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {

            //2018年04月09日因为报错修改添加new Handler
            //Attempt to read from field 'int android.view.View.mViewFlags' on a null object reference
            new android.os.Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    //原始代码
                    dismissImmediately();
                }
            });

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };


    /**
     * 主要用于拓展View的时候有输入框，键盘弹出则设置MarginBottom往上顶，避免输入法挡住界面
     */
    public void setMarginBottom(int marginBottom) {
        Context context = contextWeak.get();
        if (context == null)
            return;

        int margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_alert_left_right);
        params.setMargins(margin_alert_left_right, 0, margin_alert_left_right, marginBottom);
        contentContainer.setLayoutParams(params);
    }

    public AlertView setCancelable(boolean isCancelable) {

        View view = rootView.findViewById(R.id.outmost_container);

        //bugly发现了报错
        //#8705 java.lang.NullPointerException
        //Attempt to invoke virtual method 'android.view.View android.view.ViewGroup.findViewById(int)' on a null object reference
        //com.dgj.dinggovern.imagespick.alertview.AlertView.setCancelable(AlertView.java:504)

        if (view != null) {

            if (isCancelable) {
                view.setOnTouchListener(onCancelableTouchListener);
            } else {
                view.setOnTouchListener(null);
            }

            return this;

        } else {

            //LogUtils.d("itchen--AlertView--的根是空值");

            return null;

        }

        //return null;
        //如果发现是空的再次执行
        //return setCancelable(true);
    }

    /**
     * Called when the user touch on black overlay in order to dismiss the dialog
     */
    private final View.OnTouchListener onCancelableTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                dismiss();
            }
            return false;
        }
    };

    /**
     * Builder for arguments
     */
    public static class Builder {
        private Context context;
        private Style style;
        private String title;
        private String msg;
        private String cancel;
        private String[] destructive;
        private String[] others;
        private OnItemClickListener onItemClickListener;

        public Builder setContext(Context context) {
            this.context = context;
            return this;
        }

        public Builder setStyle(Style style) {
            if (style != null) {
                this.style = style;
            }
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setMessage(String msg) {
            this.msg = msg;
            return this;
        }

        public Builder setCancelText(String cancel) {
            this.cancel = cancel;
            return this;
        }

        public Builder setDestructive(String... destructive) {
            this.destructive = destructive;
            return this;
        }

        public Builder setOthers(String[] others) {
            this.others = others;
            return this;
        }

        public Builder setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
            return this;
        }

        public AlertView build() {
            return new AlertView(this);
        }
    }
}
